package com.crape.topic.bo.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.crape.account.bo.IAccountBO;
import com.crape.common.enums.ArticleStatusType;
import com.crape.common.exceptions.BOException;
import com.crape.common.model.AccountInfo;
import com.crape.common.model.Article;
import com.crape.common.model.ArticleComment;
import com.crape.common.model.ArticleLabelRef;
import com.crape.common.model.ArticleReply;
import com.crape.common.model.ArticleVisitor;
import com.crape.common.model.Subject;
import com.crape.common.utils.DateUtils;
import com.crape.topic.bo.IArticleBO;
import com.crape.topic.bo.ISubjectBO;
import com.crape.topic.dao.IArticleCommentDAO;
import com.crape.topic.dao.IArticleDAO;
import com.crape.topic.dao.IArticleLabelRefDAO;
import com.crape.topic.dao.IArticleVisitorDAO;

@Service
public class ArticleBOImpl implements IArticleBO {

	private IAccountBO accountBOImpl;
	private ISubjectBO subjectBOImpl;
	private IArticleDAO articleDAO;
	private IArticleCommentDAO articleCommentDAOImpl;
	private IArticleLabelRefDAO articleLabelRefDAOImpl;
	private IArticleVisitorDAO articleVisitorDAOImpl;

	@Autowired
	public void setAccountBOImpl(IAccountBO accountBOImpl) {
		this.accountBOImpl = accountBOImpl;
	}

	@Autowired
	public void setSubjectBOImpl(ISubjectBO subjectBOImpl) {
		this.subjectBOImpl = subjectBOImpl;
	}

	@Autowired
	public void setArticleDAO(IArticleDAO articleDAO) {
		this.articleDAO = articleDAO;
	}

	@Autowired
	public void setArticleCommentDAOImpl(IArticleCommentDAO articleCommentDAOImpl) {
		this.articleCommentDAOImpl = articleCommentDAOImpl;
	}

	@Autowired
	public void setArticleLabelRefDAOImpl(IArticleLabelRefDAO articleLabelRefDAOImpl) {
		this.articleLabelRefDAOImpl = articleLabelRefDAOImpl;
	}

	@Autowired
	public void setArticleVisitorDAOImpl(IArticleVisitorDAO articleVisitorDAOImpl) {
		this.articleVisitorDAOImpl = articleVisitorDAOImpl;
	}

	@Override
	public List<Article> searchArticles(String searchValue, Integer startIndex, Integer pageSize) throws BOException {
		if (startIndex == null || pageSize == null) {
			return null;
		}
		if (searchValue == null || searchValue.isEmpty()) {
			searchValue = null;
		}
		List<Article> list = articleDAO.searchArticles(searchValue, startIndex, pageSize);
		if (list == null) {
			return null;
		}
		for (Article article : list) {
			AccountInfo account = accountBOImpl.getAccountInfoById(article.getAccountid());
			article.setUsername(account.getUsername());
			article.setCreator(account);
		}
		return list; 
	}

	@Override
	public Long countSearchArticles(String searchValue) throws BOException {
		if (searchValue == null || searchValue.isEmpty()) {
			searchValue = null;
		}
		return articleDAO.countSearchArticles(searchValue);
	}

	@Override
	public List<Article> getArticles(Article article) throws BOException {
		if (article == null) {
			return null;
		}
		return articleDAO.listArticles(article);
	}

	@Override
	public Article getArticleId(Long id) throws BOException {
		if (id == null) {
			return null;
		}
		Article article = new Article();
		article.setId(id);
		List<Article> list = articleDAO.listArticles(article);
		if (list == null || list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public Article getArticleDetailId(Long id) throws BOException {
		if (id == null) {
			return null;
		}
		Article param = new Article();
		param.setId(id);
		List<Article> list = articleDAO.listArticles(param);
		if (list == null || list.isEmpty()) {
			return null;
		}
		Article article = list.get(0);
		Subject subject = subjectBOImpl.getSubjectById(article.getSubjectid());
		article.setSubjectTitle(subject.getTitle());
		return article;
	}

	@Override
	public List<Article> getNext4Articles(Long subjectid, Long articleid) throws BOException {
		if (subjectid == null || articleid == null) {
			return null;
		}
		return articleDAO.getNext4Articles(subjectid, articleid);
	}

	@Override
	public List<Article> getAuthorOtherArticles(Long accountid, Long articleid) throws BOException {
		if (accountid == null || articleid == null) {
			return null;
		}
		return articleDAO.getAuthorOtherArticles(accountid, articleid, 5);
	}

	@Override
	public List<Article> getSubjectOtherArticles(Long subjectid, Long articleid) throws BOException {
		if (subjectid == null || articleid == null) {
			return null;
		}
		List<Article> list = articleDAO.getSubjectOtherArticles(subjectid, articleid, 10);
		if (list == null) {
			return null;
		}
		for (Article article : list) {
			AccountInfo account = accountBOImpl.getAccountInfoById(article.getAccountid());
			article.setUsername(account.getUsername());
			article.setCreator(account);
		}
		return list;
	}

	@Override
	public List<ArticleComment> getArticleCommentByArticleId(Long articleid, Integer startIndex, Integer pageSize) {
		if (articleid == null) {
			return null;
		}
		ArticleComment params = new ArticleComment();
		params.setArticleid(articleid);
		List<ArticleComment> comments = articleCommentDAOImpl.getPagedArticleCommentsByArticleId(articleid, startIndex, pageSize);
		if (comments == null || comments.isEmpty()) {
			return null;
		}
		for (ArticleComment comment : comments) {
			AccountInfo accountInfo = accountBOImpl.getAccountInfoById(comment.getAccountid());
			comment.setImage(accountInfo.getImages()[3]);
			comment.setUsername(accountInfo.getUsername());
			ArticleReply commentReply = new ArticleReply();
			commentReply.setArticleid(articleid);
			commentReply.setCommentid(comment.getId());
			List<ArticleReply> replys = articleCommentDAOImpl.getArticleReplys(commentReply);
			if (replys != null && !replys.isEmpty()) {
				for (ArticleReply reply : replys) {
					AccountInfo replyAccountInfo = accountBOImpl.getAccountInfoById(reply.getAccountid());
					reply.setImage(replyAccountInfo.getImages()[3]);
					reply.setUsername(replyAccountInfo.getUsername());
					if (reply.getReaccountid() != null && reply.getReaccountid() != 0 && reply.getReaccountid() != reply.getAccountid()) {
						AccountInfo replyReaccountInfo = accountBOImpl.getAccountInfoById(reply.getReaccountid());
						reply.setReImage(replyReaccountInfo.getImages()[3]);
						reply.setReUsername(replyReaccountInfo.getUsername());
					}
				}
			}
			comment.setReplys(replys);
		}
		return comments;
	}

	@Override
	public ArticleComment getLatestArticleCommentByaccountId(Long accountid, Long articleid) {
		ArticleComment params = new ArticleComment();
		params.setAccountid(accountid);
		params.setArticleid(articleid);
		params.setRowNum(1);
		List<ArticleComment> list = articleCommentDAOImpl.listArticleComments(params);
		if (list == null || list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public List<Article> getAllArticles(Integer startIndex, Integer pageSize) throws BOException {
		if (startIndex == null || pageSize == null || pageSize == 0) {
			return null;
		}
		List<Article> resultList = articleDAO.getAllArticles(startIndex, pageSize);
		if (resultList != null && !resultList.isEmpty()) {
			for (Article obj : resultList) {
				// 设置主题title
				Long subjectid = obj.getSubjectid();
				Subject subject = subjectBOImpl.getSubjectById(subjectid);
				obj.setSubjectTitle(subject.getTitle());
				// 设置用户名
				Long userid = obj.getAccountid();
				AccountInfo account = accountBOImpl.getAccountInfoById(userid);
				obj.setUsername(account.getUsername());
				obj.setCreator(account);
			}
		}
		return resultList;
	}

	@Override
	public Long countAllArticles() throws BOException {
		return articleDAO.countAllArticles();
	}

	@Override
	public List<Article> getArticlesByAccountid(Long accountid, Integer startIndex, Integer pageSize) throws BOException {
		if (accountid == null || startIndex == null || pageSize == null || pageSize == 0) {
			return null;
		}
		AccountInfo account = accountBOImpl.getAccountInfoById(accountid);
		if (account == null) {
			return null;
		}
		List<Article> resultList = articleDAO.getArticlesByAccountid(accountid, startIndex, pageSize);
		if (resultList != null && !resultList.isEmpty()) {
			for (Article obj : resultList) {
				// 设置主题title
				Long subjectid = obj.getSubjectid();
				Subject subject = subjectBOImpl.getSubjectById(subjectid);
				obj.setSubjectTitle(subject.getTitle());
				obj.setUsername(account.getUsername());
				obj.setCreator(account);
			}
		}
		return resultList;
	}

	@Override
	public Long countArticlesByAccountid(Long accountid) throws BOException {
		if (accountid == null) {
			return null;
		}
		return articleDAO.countArticlesByAccountid(accountid);
	}

	@Override
	public List<Article> getCommentArticlesByAccountid(Long accountid, Integer startIndex, Integer pageSize) throws BOException {
		if (accountid == null || startIndex == null || pageSize == null || pageSize == 0) {
			return null;
		}
		AccountInfo account = accountBOImpl.getAccountInfoById(accountid);
		if (account == null) {
			return null;
		}
		List<Article> resultList = articleDAO.getCommentArticlesByAccountid(accountid, startIndex, pageSize);
		if (resultList != null && !resultList.isEmpty()) {
			for (Article obj : resultList) {
				// 设置主题title
				Long subjectid = obj.getSubjectid();
				Subject subject = subjectBOImpl.getSubjectById(subjectid);
				obj.setSubjectTitle(subject.getTitle());
				obj.setUsername(account.getUsername());
				obj.setCreator(account);
				// 设置回复
				ArticleComment latestArticleComment = this.getLatestArticleCommentByaccountId(accountid, obj.getId());
				obj.setLatestArticleComment(latestArticleComment);
			}
		}
		return resultList;
	}

	@Override
	public Long countArticleCommentsByAccountid(Long accountid) throws BOException {
		if (accountid == null) {
			return null;
		}
		return articleDAO.countCommentArticlesByAccountid(accountid);
	}

	@Override
	public List<Article> getArticlesBySubjectid(Long subjectid, Integer startIndex, Integer pageSize) throws BOException {
		List<Article> resultList = articleDAO.getArticlesBySubjectid(subjectid, startIndex, pageSize);
		if (resultList != null && !resultList.isEmpty()) {
			Subject subject = subjectBOImpl.getSubjectById(subjectid);
			for (Article obj : resultList) {
				// 设置主题title
				obj.setSubjectTitle(subject.getTitle());
				// 设置用户名
				Long userid = obj.getAccountid();
				AccountInfo account = accountBOImpl.getAccountInfoById(userid);
				obj.setUsername(account.getUsername());
				obj.setCreator(account);
			}
		}
		return resultList;
	}

	@Override
	public Long countArticlesBySubjectid(Long subjectid) throws BOException {
		return articleDAO.countArticlesBySubjectid(subjectid);
	}

	@Override
	public List<Article> getHotArticles() throws BOException {
		List<Article> list = articleDAO.getHotArticles();
		if (list == null) {
			return null;
		}
		for (Article article : list) {
			AccountInfo account = accountBOImpl.getAccountInfoById(article.getAccountid());
			if (account != null) {
				article.setUsername(account.getUsername());
				article.setCreator(account);
			}
			Subject subject = subjectBOImpl.getSubjectById(article.getSubjectid());
			if (subject != null) {
				article.setSubjectTitle(subject.getTitle());
			}
		}
		return list;
	}

	@Override
	public void addArticle(Article article) throws BOException {
		if (article == null || article.getStatus() == null) {
			return;
		}
		if (article.getStatus() == ArticleStatusType.published.getCode()) {
			article.setPublishdate(DateUtils.formatDate(Calendar.getInstance().getTime(), DateUtils.format));
		}
		Long articleId = articleDAO.insertArticle(article);
		List<ArticleLabelRef> list = this.makeArticleLabelRefs(articleId, article.getLabel());
		articleLabelRefDAOImpl.insertArticleLabelRef(list);
		if (article.getStatus() == ArticleStatusType.published.getCode()) {
			accountBOImpl.statAccountArticle(article.getAccountid());
		}
	}

	private List<ArticleLabelRef> makeArticleLabelRefs(Long articleId, String label) {
		List<ArticleLabelRef> labelRefs = new ArrayList<ArticleLabelRef>();
		String[] labels = label.split(" ");
		for (String lab : labels) {
			ArticleLabelRef labelRef = new ArticleLabelRef();
			labelRef.setArticleid(articleId);
			labelRef.setLabel(lab);
			labelRefs.add(labelRef);
		}
		return labelRefs;
	}

	@Override
	public void updateArticle(Article article) throws BOException {
		if (article == null) {
			return;
		}
		articleDAO.updateArticle(article);
		articleLabelRefDAOImpl.deleteArticleLabelRef(article.getId());
		List<ArticleLabelRef> list = this.makeArticleLabelRefs(article.getId(), article.getLabel());
		articleLabelRefDAOImpl.insertArticleLabelRef(list);
		if (article.getStatus() == ArticleStatusType.published.getCode()) {
			accountBOImpl.statAccountArticle(article.getAccountid());
		}
	}

	@Override
	public void updateArticleStatus(Long accountid, Long articleid, Integer status) throws BOException {
		if (articleid == null || status == null) {
			return;
		}
		Article article = new Article();
		article.setId(articleid);
		article.setStatus(status);
		articleDAO.updateArticle(article);
		if (article.getStatus() == ArticleStatusType.published.getCode()) {
			accountBOImpl.statAccountArticle(accountid);
		}
	}

	@Override
	public void deleteArticleById(Long id) throws BOException {
		if (id == null) {
			return;
		}
		articleDAO.deleteArticleById(id);
	}

	@Override
	public void addComment(ArticleComment articleComment) {
		if (articleComment == null || articleComment.getArticleid() == null) {
			return;
		}
		if (articleComment.getComment() == null || articleComment.getComment().isEmpty()) {
			return;
		}
		articleCommentDAOImpl.insertArticleComment(articleComment);
		Long count = articleDAO.countArticleCommentsByid(articleComment.getArticleid());
		articleDAO.updateArticleComments(articleComment.getArticleid(), count);
	}

	@Override
	public void addReply(ArticleReply articleReply) {
		if (articleReply == null) {
			return;
		}
		articleCommentDAOImpl.insertArticleReply(articleReply);
		Long count = articleDAO.countArticleReplysByid(articleReply.getArticleid());
		articleDAO.updateArticleReplys(articleReply.getArticleid(), count);
	}

	@Override
	public void addVisitor(Long visitorid, Long articleid) {
		if (visitorid == null || articleid == null) {
			return;
		}
		articleDAO.addArticleViews(articleid);
		ArticleVisitor articleVisitor = articleVisitorDAOImpl.getArticleVisitor(visitorid, articleid);
		if (articleVisitor == null) {
			articleVisitorDAOImpl.insertArticleVisitor(visitorid, articleid);
		} else {
			articleVisitorDAOImpl.updateArticleVisitor(visitorid, articleid);
		}
		Long count = articleDAO.countArticleVisitorsByid(articleid);
		articleDAO.updateArticleVisitors(articleid, count);
	}

}
